import info.gridworld.grid.AbstractGrid;
import info.gridworld.grid.Location;

import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public class SparseBoundedGrid<E> extends AbstractGrid<E> {

    // HashMap store the number of Loaction and gird occupant
    private Map<Location, E> occMap;
    private int nRows;
    private int nCols;

    // Constructer
    public SparseBoundedGrid(int rows, int cols) {
        occMap = new HashMap<Location, E>();
        nRows = rows;
        nCols = cols;
    }

    // get Method
    public int getNumRows() {
        return nRows;
    }

    public int getNumCols() {
        return nCols;
    }

    // Judge the location is vaild
    public boolean isValid(Location loc) {
        int r = loc.getRow();
        int c = loc.getCol();
        if ((r >= 0) && (c < getNumRows()) && (r >= 0) && (c <= getNumCols())) {
            return true;
        }
        return false;
    }

    // return the location of that the number of grid occupant
    // return_type: ArrayList<Location>
    public ArrayList<Location> getOccupiedLocations() {
        ArrayList<Location> locs = new ArrayList<Location>();

        // occMap.keySet() is the set of Loactions
        for (Location loc : occMap.keySet()) {
            locs.add(loc);
        }
        return locs;
    }

    // return_type : E (usually Actor)
    public E get(Location loc) {
        if (loc == null) {
            throw new IllegalArgumentException("Error! Location: " + loc + " is InValid.");
        }
        return occMap.get(loc);
    }

    // put the new occupant to the location
    public E put(Location loc, E obj) {
        if (loc == null) {
            throw new IllegalArgumentException("Error! Location: " + loc + " is InValid.");
        }
        if (obj == null) {
            throw new IllegalArgumentException("Error! obj == null");
        }
        // direct call Map.put method
        return occMap.put(loc, obj);
    }

    // remove the Obj by index location
    public E remove(Location loc) {
        if (loc == null) {
            throw new IllegalArgumentException("Error! Location: " + loc + " is InValid.");
        }
        return occMap.remove(loc);
    }
}
